package nafos.server.monitor

import io.netty.channel.Channel
import nafos.server.NafosServer
import nafos.server.SocketConfiguration
import nafos.server.relation.IoCache
import nafos.server.relation.NameSpace
import org.slf4j.LoggerFactory
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

/**
 *@ClassName ChannelConnectManager
 *@Description channel连接管理，最开始连接的channel都在这里，
 * 登录之后或者通过安全验证确实是有效用户之后删除
 * 否则在一定时间内关闭连接
 *@Author hxy
 *@Date 2020/1/9 12:20
 */
object ChannelConnectManager {
    private val logger = LoggerFactory.getLogger(ChannelConnectManager::class.java)

    private val noSecurityChannelMap = ConcurrentHashMap<Channel, Long>(1024)

    /**
     * 连接
     *
     * @param channel
     */
    @JvmStatic
    fun connect(channel: Channel) {
        noSecurityChannelMap[channel] = System.currentTimeMillis()
    }

    /**
     * 通过安全验证
     *
     * @param channel
     */
    @JvmStatic
    fun safe(channel: Channel?) {
        noSecurityChannelMap.remove(channel)
    }

    /**
     * 关闭不安全的链接
     */
    @JvmStatic
    fun closeUnSafeChannel(timeOut: Long) {
        val time = System.currentTimeMillis()
        noSecurityChannelMap.forEach { (t: Channel, u: Long) ->
            if (time -u > timeOut) {
                t.close()
                noSecurityChannelMap.remove(t)
                logger.info("删除无效的用户连接：{}", t.toString())
            }
        }
    }

    init {
        Thread(Runnable {
            Thread.currentThread().name = "UnSafeSocketChannel"
            while (true) {
                try {
                    Thread.sleep(TimeUnit.SECONDS.toMillis(30))
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
                closeUnSafeChannel((NafosServer.configuration as SocketConfiguration).unsafeTimeOut * 1000)
                // 打印连接数
                IoCache.spaceClientMap.forEach {k,v->
                    logger.info("nameSpace:$k  clientSize:${v.obj.size}")
                }
            }
        }).start()
    }
}